package org.example.web;

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.example.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/*
    熔断器的使用方式：
        第1种（加在对应的方法上）： 直接在需要进行熔断监控的方法上，添加一个注解：
            @HystrixCommand(fallbackMethod = "fallbackMethod")//方法熔断
            特点：1. 托底方法的返回类型要与加该注解的方法一样； 2. 托底方法的参数个数要与对应的方法一致

       第2种（加在类上）： 这种配置方式，会对整个接口中，所有的方法都有效，而且作用的效果都一样。
            @DefaultProperties(defaultFallback = "defaultFallbackMethod") //统一降级配置
            注意事项：这种试，托底的方法是不能有  返回类型和参数个数的

 */

@RestController
@RequestMapping("/order")
@DefaultProperties(defaultFallback = "defaultFallbackMethod") //统一降级配置
public class OrderController {
    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand //只需要添加此注解，就可以被 统一熔断管理
    @GetMapping("/getorder")
//    @HystrixCommand(fallbackMethod = "fallbackMethod")
    public User getOrder() {
        //像下面这种发请求的方法，是一种  典型的 restfult风格的请求
        String url = "http://USER-SERVER/user/getinfo";
        //通过resttemplate工具，进行模拟 http的请求
        User user = restTemplate.getForObject(url, User.class);
        return user;
    }

    //托底方法
    //TODO 注意：托底对应的方法，要与它的返回结果类型相同; 参数个数也要相同
    public User fallbackMethod() {
        //在返回 托底结果的同时，是不是也可以向【运维人员】发送通知
        //返回托底数据,友好的提示信息
        return new User(-1L, "无此用户", "用户服务不可用，执行托底方法");
    }

    //统一降级配置-托底方法
    public User defaultFallbackMethod(){
        //返回托底数据,友好的提示信息
        return new User(-1L ,"无此用户","用户服务不可用，执行托底方法 | 统一降级配置");
    }

}
